#pragma once
#include "log.hpp"
#include <cerrno>
#include <cstdint>
#include <cstring>
#include<iostream>
#include <string>
#include<unordered_map>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>

// namespace yangyi
// {
//     using namespace std;
//     class UdpServer
//     {
//     public:
//         UdpServer(uint16_t port,string ip="")
//         :_sock(-1)
//         ,_port(port)
//         ,_ip(ip)
//         {

//         }
//         bool initServer()
//         {
//             int _sock=socket(AF_INET,SOCK_DGRAM,0);
//             if(_sock < 0)
//             {
//                 logMessage(FATAL,"%d:%s",errno,strerror(errno));
//                 exit(1);
//             }
//             struct sockaddr_in server;
//             bzero(&server,sizeof(server));
//             server.sin_family=AF_INET;
//             server.sin_port=htons(_port);
//             server.sin_addr.s_addr=_ip.empty()?INADDR_ANY:inet_addr(_ip.c_str());
//             if(bind(_sock,(struct sockaddr*)&server,sizeof(server)) < 0)
//             {
//                 logMessage(FATAL,"%d:%s",errno,strerror(errno));
//                 exit(2);
//             }
//             logMessage(NORMAL,"the udpserver done:%s",strerror(errno));
//         }
//         void start()
//         {
//             char buffer[1024];
//             while(true)
//             {
//                 struct sockaddr_in client;
//                 bzero(&client,sizeof(client));
//                 socklen_t len=sizeof(client);
//                 char key[64];
//                 ssize_t s=recvfrom(_sock,buffer,sizeof(buffer),0,
//                 (struct sockaddr*)&client,&len);
//                 if(s > 0)
//                 {
//                     buffer[s]=0;
//                     string client_ip=inet_ntoa(client.sin_addr);
//                     uint16_t client_port=ntohs(client.sin_port);
//                     snprintf(key,sizeof(key),"%s-%u",client_ip.c_str()
//                     ,client_port);
//                     auto it=_users.find(key);
//                     if(it==_users.end()){
//                         _users.insert({key,client});
//                     }
//                 }
//                 for(auto& iter:_users)
//                 {
//                     string message=key;
//                     message+="#";
//                     message+=buffer;
//                     sendto(_sock,message.c_str(),message.size(),
//                     0,(struct sockaddr*)&client,len);
//                 }
//             }
//         }
//         //关掉sock切断联系
//         ~UdpServer(){
//             if(_sock >= 0){
//                 close(_sock);
//             }
//         }
//     private:
//         int _sock;
//         string _ip;
//         uint16_t _port;
//         unordered_map<string,struct sockaddr_in> _users;
//     };
// }
class UdpServer
{
public:
    UdpServer(uint16_t port,std::string ip="")
    :_port(port),_ip(ip)
    ,_sock(-1)
    {

    }
    void initServer()
    {

    }
    void start()
    {

    }
    ~UdpServer()
    {
        
    }
private:
    std::string _ip;
    uint16_t _port;
    int _sock;
    std::unordered_map<std::string,struct sockaddr_in>_users;
};
// class UdpServer
// {
// public: 
//     UdpServer(uint16_t port,std::string ip="")
//     :_port(port)
//     ,_ip(ip)
//     ,_sock(-1)
//     {

//     }
//     bool initServer3()
//     {
//         _sock=socket(AF_INET,SOCK_DGRAM,0);
//         if(_sock < 0)
//         {
//             logMessage(FATAL,"%s:%d",errno,strerror(errno));
//             exit(1);
//         }
//         struct sockaddr_in server;
//         bzero(&server,sizeof(server));
//         server.sin_family=AF_INET;
//         server.sin_port=htons(_port);
//         server.sin_addr.s_addr=_ip.empty()?INADDR_ANY:inet_addr(_ip.c_str());
//         if(bind(_sock,(struct sockaddr*)&server,sizeof(server)) < 0)
//         {
//             logMessage(FATAL,"%d:%s",errno,strerror(errno));
//             exit(3);
//         }
//         logMessage(NORMAL,"the udpserver has done:%s",strerror(errno));
//         return true;   
//     }
//     void start()
//     {
//         char buffer[1024];
//         while(true)
//         {
//             struct sockaddr_in client;
//             bzero(&client,sizeof(client));
//             socklen_t len=sizeof(client);
//             char key[64];
//             ssize_t s=recvfrom(_sock, buffer, sizeof(buffer),
//             0, (struct sockaddr*)&client, &len);
//             if(s > 0)
//             {
//                 buffer[s]=0;

//                 uint16_t client_port=ntohs(client.sin_port);
//                 std::string client_ip=inet_ntoa(client.sin_addr);
//                 snprintf(key,sizeof(key),"%s-%u",
//                 client_ip.c_str(),client_port);
//                 logMessage(NORMAL,"key:%s",key);
//                 auto it=_users.find(key);
//                 if(it==_users.end()){
//                     _users.insert({key,client});
//                 }
//             }
//             for(auto& iter:_users){
//                 std::string message=key;
//                 message+="#";
//                 message+=buffer;
//                 sendto(_sock,message.c_str(),
//                 message.size(),0,(struct sockaddr*)&client,len);
//             }
//         }
//     }
//     ~UdpServer(){
//         if(_sock >= 0){
//             close(_sock);
//         }
//     }
//     bool initServer2()
//     {
//         _sock=socket(AF_INET,SOCK_DGRAM,0);
//         if(_sock < 0)
//         {
//             //这里要根据格式化字符串的形式将可变参数打印出来
//             logMessage(FATAL, "%d:%s", 
//             errno,strerror(errno));
//             exit(1);
//         }
//         struct sockaddr_in server;
//         bzero(&server,sizeof(server));
//         server.sin_family=AF_INET;
//         server.sin_port=htons(_port);
//         server.sin_addr.s_addr=_ip.empty()?INADDR_ANY:inet_addr(_ip.c_str());
//         if(bind(_sock,(struct sockaddr*)&server,sizeof(server)) < 0)
//         {
//             logMessage(FATAL,"%d:%s",errno,strerror(errno));
//             exit(2);
//         }
//         logMessage(NORMAL, "init udp server done...%s", strerror(errno));
//         return true;
//     }
//     void initServer()
//     {
//         _sock=socket(AF_INET, SOCK_DGRAM, 0);
//         if(_sock < 0){
//             logMessage(FATAL,"%d:%s",errno,strerror(errno));
//             exit(2);
//         }
//         struct sockaddr_in server;
//         bzero(&server,sizeof(server));
//         server.sin_family=AF_INET;
//         server.sin_port=htons(_port);
//         server.sin_addr.s_addr=inet_addr(_ip.c_str());
//         if(bind(_sock,(struct sockaddr*)&server,sizeof(server)) < 0)
//         {
//             logMessage(FATAL, "%d:%s",errno,strerror(errno));
//             exit(3);
//         }
//         logMessage(NORMAL, "init udp server done ...%s", strerror(errno));
//     }
// private:
//     int _sock;
//     std::string _ip;
//     uint16_t _port;
//     std::unordered_map<std::string, struct sockaddr_in> _users;
// };
